﻿using Needle.Framework;
using Needle.Utils;
using Needle.Utils.Extensions;

namespace Needle.Core.Lifetime
{

    /// <summary></summary>
    public class InstanceTracker : Component, IInstanceTracker
    {

        /// <summary></summary>
        public InstanceTracker(InstanceId instanceId, IReference reference)
        {
            Ensure.NotNull(instanceId, "instanceId");
            Ensure.NotNull(reference, "reference");
            _InstanceId = instanceId;
            _Reference = reference;
        }

        #region IInstanceTracker Members

        private IReference _Reference;

        /// <summary></summary>
        public bool TryGetTarget(out object target)
        {
            IReference reference = _Reference;
            target = reference.Target;
            if (!reference.IsValid)
            {
                target = null;
                return false;
            }
            return true;
        }

        private InstanceId _InstanceId;
        /// <summary></summary>
        public InstanceId InstanceId
        {
            get { return _InstanceId; }
        }

        #endregion

        /// <summary></summary>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _Reference = null;
            }
            base.Dispose(disposing);
        }

        private const string DisplayString = "InstanceTracker of '{0}' ({1}) with {2}";

        /// <summary></summary>
        public override string ToString()
        {

            string instanceIdName = InstanceId.Name != null ? InstanceId.Name : "<unnamed>";
            IReference reference = _Reference;
            object refTypeName = reference == null ? null : reference.GetType().Name;
            return DisplayString.FormattedWith(
                instanceIdName,
                InstanceId.Type.Name,
                refTypeName);
        }
    }
}
